var gcd = (x = Math.abs(x), y = Math.abs(y)) => {
    while (y) {
        var t = y;
        y = x % y;
        x = t;
    }
    return x;
}
var simplify = ([a, b]) => [a / gcd(a, b), b / gcd(a, b)]

var arr = [
    [1, 1],
    [-1, 2]
]

var factorial_caches = { '0': 1, '1': 1 }

var f = (x) => {
    if (factorial_caches[x]) return factorial_caches[x];
    if (x > 1) {
        var temp = x * f(x - 1);
        factorial_caches[x] = temp;
        return factorial_caches[x];
    } else {
        factorial_caches[x] = 1;
        return factorial_caches[x];
    }
}


function comb(m, n) {
    return Math.round(f(m) / (f(n) * f(m - n)))
}

function _b(i) {

    if (i % 2 == 0) {
        arr.push([0, 1]);
    } else {
        var n = i;
        var product_denominators = 1
        var triangles = []
        for (var k = 0; k < n; k += 1) {
            var p = comb(n, k);
            triangles.push(p);
            if (arr[k]) product_denominators *= arr[k][1];
        }
        //console.log(triangles)
        //console.log('分母乘积为', product_denominators)
        //console.log('系数为', triangles)
        var sum_numerator = 0;
        for (var k = 0; k < n - 1; k += 1) {
            var p = (product_denominators * arr[k][0] / arr[k][1]) * triangles[k];
            //console.log(`第${k}项分子通分后为${p}`)
            sum_numerator += p;
        }
        var [a, b] = simplify([-sum_numerator, product_denominators * triangles[triangles.length - 1]])
        if (a * b < 0) {
            if (a > 0) arr.push([-1 * a, -1 * b]);
            else arr.push([a, b]);
        } else {
            arr.push([a, b]);
        }
    }
}


function b(i) {
    if (i % 2 && i > 1) return [0, 1]
    if (i < arr.length) return arr[i];
    else {
        for (var k = arr.length + 1; k <= i + 1; k++) _b(k);
        return arr[i]
    }
}


function series(k, nb) {
    if (k > 0 && k % 2 === 0) {
        var temp = b(k);
        var bk = Math.abs(temp[0] / temp[1]);
        var fk = parseInt(f(k))
        return (1 / 2) * bk * (2 * Math.PI) ** k / fk;
    } else if (k > 0 && k % 2) {
        var sum = 0;
        for (var i = 1; i < nb; i++) {
            sum += 1 / (i) ** k;
        }
        return sum
    } else if (k < 0) {
        var temp = b(1 - k);
        var bk = Math.abs(temp[0] / temp[1]);
        return (-1) ** (-k) * bk / (1 - k)
    }
}


